package com.bluetooth.phone.optionb;

import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;

import com.bluetooth.phone.LogUtils;
import com.bluetooth.phone.multi.BaseViewHolder;

public class ItemDragHelper {
    public static final int NONE = -1;
    public static final String TAG = "ItemDragHelper";

    private OnItemDragListener dragListener = new EmptyDragListener();
    private RecyclerView horizontalRecycler;
    private FrameLayout mLayoutParent;
    private DragFloatViewHelper floatViewHelper;
    private boolean isDrag;

    private int lastRecyclerPos = NONE;
    private RecyclerView lastRecyclerView;
    private int lastItemPos = NONE;
    private float lastTouchRawX;
    private float lastTouchRawY;
    private int itemViewHeight;

    /**
     * 横向滚动的RecyclerView
     *
     * @param
     */

    public ItemDragHelper(FrameLayout layoutParent) {
        mLayoutParent = layoutParent;
        floatViewHelper = new DragFloatViewHelper();
    }

    /**
     * 开始拖拽
     *
     * @param viewHolder 选中的Item的ViewHolder
     */
    public void startDrag(@NonNull BaseViewHolder viewHolder) {
        View itemView = viewHolder.itemView;
        int itemPosition = viewHolder.getBindingAdapterPosition();
      if (!dragListener.onItemSelected(viewHolder, itemView, itemPosition)) {
           return;
       }
        isDrag = true;
        initParams();
        lastItemPos = itemPosition;
        dragListener.onDragStart();
        floatViewHelper.createView(itemView, lastTouchRawX, lastTouchRawY, dragListener.getScale());
     //   dragListener.onDrawFloatView(floatViewHelper.getFloatView());


        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) itemView.getLayoutParams();
        itemViewHeight = itemView.getHeight() + params.topMargin + params.bottomMargin;
    }

    private void initParams() {
        lastRecyclerPos = NONE;
        lastRecyclerView = null;
    }

    /**
     * 设置拖拽回调Listener
     *
     * @param onItemDragListener 回调Listener
     */
    public void addOnItemDragListener(@NonNull OnItemDragListener onItemDragListener) {
        this.dragListener = onItemDragListener;
    }

    public RecyclerView getHorizontalRecycler() {
        return horizontalRecycler;
    }

    /**
     * 必须完整处理Touch事件，可以在Activity或者外层的ViewGroup或可以拦截Touch事件的地方回调都可以
     *
     * @param event touch的event
     * @return true表示消耗掉事件
     */
    public boolean onTouch(@NonNull MotionEvent event) {
        lastTouchRawX = event.getRawX();
        lastTouchRawY = event.getRawY();
        if (!isDrag) {
            return false;
        }
        //如果drag过程没有MOVE事件，lastVerticalPos和lastRecyclerView是不能被正确初始化的，这样dragFinish回调就会有问题
//        if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
        floatViewHelper.updateView((int) lastTouchRawX, (int) lastTouchRawY);
       moveIfNecessary(lastTouchRawX, lastTouchRawY);
      //  scrollRunnableStart();
//        }

        if (event.getActionMasked() == MotionEvent.ACTION_UP ||
                event.getActionMasked() == MotionEvent.ACTION_CANCEL ) {
            stopDrag();
        }

        return true;
    }

    private void scrollRunnableStart() {
        if (lastRecyclerView != null) {
            lastRecyclerView.removeCallbacks(scrollRunnable);
            scrollRunnable.run();
            lastRecyclerView.invalidate();
        }
    }

    private void stopDrag() {
        if (isDrag) {
            dragListener.onDragFinish(lastRecyclerView, lastRecyclerPos, lastItemPos);
            floatViewHelper.removeView();
        }

        isDrag = false;
    }

    /**
     * Item位置更换计算
     * 根据触摸位置horizontalRecycler.findChildViewUnder(x, y)找到垂直recyclerView的位置，若找到位置继续
     * 根据上一次垂直recyclerView所在的位置，判断是否为第一次选中或者是切换recyclerView的操作，此处可通过itemDragListener回调拦截此次操作的结果
     * 如果需要切换recyclerView的位置，此时需要对被拖动的Item进行remove，并在新的recyclerView中add进去
     * 根据触摸位置recyclerView.findChildViewUnder(itemX, itemY)找到itemView的位置
     * 根据上一次itemView所在的位置，判断是否需要移动itemView位置的操作，此处可通过itemDragListener回调拦截此次操作的结果
     * 如果需要移动动itemView位置则需要把recyclerView滚动到合适的位置，防recyclerView乱跳
     *
     * 作者：free46000
     * 链接：https://www.jianshu.com/p/e2c6a315daef
     * 来源：简书
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     * 当用户拖动的时候，计算是否需要移动Item
     *
     * @param touchRawX float event.getRawX()
     * @param touchRawY float event.getRawY()
     */

    private boolean moveIfNecessary(float touchRawX, float touchRawY) {
        boolean result = true;

        // 找到当前触摸点下的RecyclerView
        float[] location = getInsideLocation(mLayoutParent, touchRawX, touchRawY);
        float x = location[0];
        float y = location[1];

        RecyclerView recyclerView;
        for (int i = 0, count = mLayoutParent.getChildCount(); i < count; i++) {
            View child = mLayoutParent.getChildAt(i);
            recyclerView = findRecyclerView(child);
            if (recyclerView != null && isPointInsideView(x, y, recyclerView)) {
                // 找到了触摸点所在的RecyclerView
                // 这里可以添加处理逻辑
                handleRecyclerViewTouch(recyclerView);
                location = getInsideLocation(recyclerView, touchRawX, touchRawY);
                float itemX = location[0];
                float itemY = location[1];
                View itemView = recyclerView.findChildViewUnder(itemX, itemY);
                int recyclerPos = getPositionByChildView(itemView);
                dragListener.onItemChanged(recyclerView,recyclerPos, lastItemPos);
                LogUtils.e(TAG, "moveIfNecessary recyclerPos==" + recyclerPos);
                LogUtils.e(TAG, "moveIfNecessary recyclerView==" + recyclerView);
            }
        }

        // 如果没有找到符合条件的RecyclerView
        return false;
    }

    // 判断点(x, y)是否在view的范围内
    private boolean isPointInsideView(float x, float y, View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int viewX = location[0];
        int viewY = location[1];

        // 判断触摸点是否在view的范围内
        return (x >= viewX && x <= viewX + view.getWidth() &&
                y >= viewY && y <= viewY + view.getHeight());
    }

    // 处理找到的RecyclerView
    private void handleRecyclerViewTouch(RecyclerView recyclerView) {
        // 这里可以添加对找到的RecyclerView的处理逻辑
    }

    // 从view中查找RecyclerView
//    private RecyclerView findRecyclerView(View view) {
//        if (view instanceof RecyclerView) {
//            return (RecyclerView) view;
//        } else if (view instanceof ViewGroup) {
//            ViewGroup viewGroup = (ViewGroup) view;
//            for (int i = 0; i < viewGroup.getChildCount(); i++) {
//                RecyclerView recyclerView = findRecyclerView(viewGroup.getChildAt(i));
//                if (recyclerView != null) {
//                    return recyclerView;
//                }
//            }
//        }
//        return null;
//    }
    /**
     * 当item位置变换，滚动recycler到正确的位置
     * TODO: 2017/2/21 0021 整理更优雅的写法  还有scrollToPosition(0)是否必要？
     */
    private void scrollToRightPositionWhenItemChanged(RecyclerView recyclerView, View itemView, int itemPos) {
        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof ItemTouchHelper.ViewDropHandler) {
            OrientationHelper helper = OrientationHelper.createVerticalHelper(layoutManager);
            int start = helper.getDecoratedStart(itemView);
            int end = helper.getDecoratedEnd(itemView);
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(
                    itemPos, lastItemPos > itemPos ? start : end - itemViewHeight);
//                System.out.println(lastItemPos + "-" + childPos + "OrientationHelperOrientationHelper:"
//                        + height + "==" + itemViewHeight + "=||=" + start + "===" + end + "||||||" + myStart + "===" + itemTargetView.getHeight() );
        }
        if (lastItemPos == 0 || itemPos == 0) {
            recyclerView.scrollToPosition(0);
        }
    }

    /**
     * 获取当前点击的位置在RecyclerView内部的坐标 (Y坐标范围0+padding到height-padding)?
     */
    private float[] getInsideLocation(RecyclerView recyclerView, float touchRawX, float touchRawY) {
        float[] result = new float[2];
        int[] location = new int[2];
        recyclerView.getLocationOnScreen(location);
        result[0] = touchRawX - location[0];
        result[1] = touchRawY - location[1];
//        System.out.println("getInsideLocation:" + result[0] + "-" + result[1] + "==" + "X:" + touchRawX + "Y:" + touchRawY);

        result[0] = result[0] / dragListener.getScale();
        result[1] = result[1] / dragListener.getScale();

        int minY = recyclerView.getPaddingTop();
        int maxY = recyclerView.getHeight() - recyclerView.getPaddingBottom();
        result[1] = Math.min(Math.max(result[1], minY), maxY);


        return result;
    }

    /**
     * 获取当前点击的位置在RecyclerView内部的坐标 (Y坐标范围0+padding到height-padding)?
     */
    private float[] getInsideLocation(View recyclerView, float touchRawX, float touchRawY) {
        float[] result = new float[2];
        int[] location = new int[2];
        recyclerView.getLocationOnScreen(location);
        result[0] = touchRawX - location[0];
        result[1] = touchRawY - location[1];
//        System.out.println("getInsideLocation:" + result[0] + "-" + result[1] + "==" + "X:" + touchRawX + "Y:" + touchRawY);

        result[0] = result[0] / dragListener.getScale();
        result[1] = result[1] / dragListener.getScale();

        int minY = recyclerView.getPaddingTop();
        int maxY = recyclerView.getHeight() - recyclerView.getPaddingBottom();
        result[1] = Math.min(Math.max(result[1], minY), maxY);


        return result;
    }

    /**
     * 当在两个RecyclerView中切换时，计算目标RecyclerView中Child位置 (若目标RecyclerView为空返回0)
     */
    private int calcItemPositionWhenChangeRecycler(RecyclerView verticalRecycler, View itemView, int itemPos, float childX, float childY) {
        //若目标RecyclerView为空返回0
        if (itemPos == NONE && verticalRecycler.getAdapter().getItemCount() == 0) {
            itemPos = 0;
        } else if (itemView != null) {
            int top = itemView.getTop();
            if ((top + itemView.getHeight() * dragListener.getMoveLimit()) < childY) {
                //证明滑动位置在targetView的下部，所以要插入到当前位置+1
                itemPos++;
            }
        }

        return itemPos;
    }

    /**
     * 从view中获取需要操作的RecyclerView
     *
     * @param view View
     */
    protected RecyclerView findRecyclerView(View view) {
        if (view == null) {
            return null;
        }

        if (view instanceof RecyclerView) {
            return (RecyclerView) view;
        } else if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            RecyclerView recyclerView;
            for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
                recyclerView = findRecyclerView(viewGroup.getChildAt(i));
                if (recyclerView != null) {
                    return recyclerView;
                }
            }
        }
        return null;
    }


    /**
     * 滚动Runnable，为了可持续滚动
     */
    private final Runnable scrollRunnable = new Runnable() {

        @Override
        public void run() {
            float[] horLocation = getInsideLocation(horizontalRecycler, lastTouchRawX, lastTouchRawY);
            float[] verLocation = getInsideLocation(lastRecyclerView, lastTouchRawX, lastTouchRawY);
            boolean isHorizontalScroll = scrollIfNecessary(horizontalRecycler, (int) horLocation[0], (int) horLocation[1]);
            boolean isVerticalScroll = scrollIfNecessary(lastRecyclerView, (int) verLocation[0], (int) verLocation[1]);
            if (isDrag && (isHorizontalScroll || isVerticalScroll)) {
                //it might be lost during scrolling
                moveIfNecessary(lastTouchRawX, lastTouchRawY);
                lastRecyclerView.removeCallbacks(scrollRunnable);
                ViewCompat.postOnAnimation(lastRecyclerView, this);
            }
        }
    };

    /**
     * 当用户滚动到边缘的时候,计算是否需要滚动
     */
    private boolean scrollIfNecessary(RecyclerView recyclerView, int curX, int curY) {
        if (!isDrag) {
            return false;
        }

        RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
        int scrollX = 0;
        int scrollY = 0;
        if (lm.canScrollHorizontally()) {
            scrollX = dragListener.calcHorizontalScrollDistance(recyclerView, curX, curY);
        }
        if (lm.canScrollVertically()) {
            scrollY = dragListener.calcVerticalScrollDistance(recyclerView, curX, curY);
        }
//        System.out.println("scroll:::::" + scrollY + "=" + recyclerView.getScrollY() + "curY::" + curY);
//        System.out.println("scroll:::::" + scrollX + "=" + recyclerView.getScrollX() + "curX::" + curX);

        if (scrollX != 0 || scrollY != 0) {
            recyclerView.scrollBy(scrollX, scrollY);
        }
        return scrollX != 0 || scrollY != 0;
    }


    /**
     * 获取需要move的目标Position，即toPosition
     *
     * @return NONE为找不到
     */
    private int getTargetItemPos(View itemTargetView, float childY, int lastRecyclerPos, int currRecyclerPos) {
        int itemPos = getPositionByChildView(itemTargetView);

        if (itemPos == NONE) {
            return itemPos;
        }

        if ((itemPos != lastItemPos || lastRecyclerPos != currRecyclerPos)) {
            return itemPos;
        }

        return NONE;
    }


    /**
     * 两个Item是否需要move
     */
    private boolean isItemNeedChange(View itemView, int lastItemPos, int itemPos, float itemY) {
        if (itemView == null || lastItemPos == NONE || itemPos == NONE || lastItemPos == itemPos) {
            return false;
        }
        int top = itemView.getTop();

        int moveLimit = (int) (top + itemView.getHeight() * dragListener.getMoveLimit());
//        System.out.println("isNeedRemove-top:" + top + "==height:" + itemView.getHeight()
//                + "==touchY:" + itemY + "moveLimit==" + moveLimit + "lastItemPos > itemPos===" + (lastItemPos > itemPos));

        if (lastItemPos > itemPos) {
//            return touchY < moveLimit && top >= 0;
            return itemY < moveLimit;
        } else {
            return itemY > moveLimit;
        }
    }

    /**
     * touch的位置是否为当前view，防止两个item切换时的抖动问题
     */
    private boolean isCurrPosition(float childY, View itemView) {
//        System.out.println("isCurrPosition:" + (childY > itemView.getTop() && childY < itemView.getBottom()));
        return childY >= itemView.getTop() && childY <= itemView.getBottom();
    }


    /**
     * 查找当前view在RecyclerView中的位置 没有返回NONE
     */
    private int getPositionByChildView(View itemView) {
        if (itemView == null) {
            return NONE;
        }
        try {
            return ((RecyclerView.LayoutParams) itemView.getLayoutParams()).getBindingAdapterPosition();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return NONE;
    }

    /**
     * 是否真正切换了RecyclerView
     * 需要注意这里把没有切换后没有touch到Item当成不是真正切换
     */
    private boolean isChangeRecyclerView(int lastRecyclerPos, int currRecyclerPos) {
        return lastRecyclerPos != currRecyclerPos && lastRecyclerPos != NONE && currRecyclerPos != NONE;
    }

    /**
     * 是否为初次选中RecycleView
     */
    private boolean isSelectedRecyclerView(int lastRecyclerPos, int currRecyclerPos) {
        return lastRecyclerPos == NONE && currRecyclerPos != NONE;
    }

    /**
     * 是否为第一次选中子ItemView
     */
    private boolean isSelectedChildView(int lastChildPos, int currChildPos) {
        return lastChildPos == NONE && currChildPos != NONE;
    }

    static class EmptyDragListener extends OnItemDragListener {

    }
}
